using MediatR;
using Microsoft.Extensions.Logging;
using Universal.Domain.Events;
namespace Universal.Infrastructure.Events;

/// <summary>
/// 使用MediatR实现领域事件调度器，可以方便地实现领域事件的异步处理。
/// <summary>
public class MediatRDomainEventDispatcher : IDomainEventDispatcher
{
    private readonly IMediator _mediator;
    private readonly ILogger<MediatRDomainEventDispatcher> _logger;
    public MediatRDomainEventDispatcher(IMediator mediator, ILogger<MediatRDomainEventDispatcher> logger)
    {
        _mediator = mediator;
        _logger = logger;
    }

    /// <summary>
    /// 调度领域事件
    /// </summary>
    /// <param name="events">要调度的领域事件集合</param>
    /// <param name="cancellationToken">用于控制异步操作的取消，不影响事件的基本处理流程</param>
    /// <returns>异步操作的结果</returns>
    public async Task DispatchAsync(IEnumerable<IDomainEvent> events, CancellationToken cancellationToken = default)
    {
        // 遍历所有领域事件
        foreach (var @event in events)
        {
            // 创建领域事件通知包装器
            var notification = new DomainEventNotification(@event);
            _logger.LogInformation("分发领域事件: 事件ID:{EventId} 事件名称:{EventName}", @event.Id, @event.GetType().Name);
            // 使用MediatR发布领域事件
            await _mediator.Publish(notification, cancellationToken);
        }
    }
}